<template>
  <!-- action 后端明确提供了上传的接口地址，表示上传接口 -->
  <!-- 但是咱们这个项目后端没有专门的上传图片接口，所以这个 action 可以指定为 # 号 -->
  <!-- list-type 指定样式，展示的类型 -->
  <!-- file-list 表示要展示的图片信息 -->
  <!-- on-preview 点击预览相关的属性 -->
  <!-- limit 表示最大的上传的数量 -->
  <!-- //!#on-remove 监听的是删除的操作，注意默认自带的删除效果，删除的仅仅是结构，还需要手动的把数据进行删除 -->
  <!-- el-upload 这个组件有两种上传方式，第一种就是给 action 指定后端的接口地址，使用它内部封装好的上传逻辑 -->
  <!-- 第二种方式是给 el-upload 指定 http-request，这个表示自定义上传 -->
  <!-- 一旦指定了 http-request，其实 el-upload 会把拿到的当前图片转换为一个 blob 地址进行展示 -->
  <!-- 真正的上传到后端/腾讯云的的业务逻辑还要自己去写 -->
  <!-- before-upload 上传之前会触发的属性，返回 false 或 Promise.reject 会终止上传 -->
  <div>
    <el-upload
      action="#"
      list-type="picture-card"
      :file-list="fileList"
      :on-preview="handdlePriview"
      :limit="1"
      :on-remove="handleRemove"
      :http-request="handleUpload"
      :on-change="changeFile"
      :before-upload="beforeUpload"
      :class="{
        // 右边的变量 isShowAdd 是 true 的情况，就是用左边的类名 isShowAdd
        isShowAdd: isShowAdd
      }"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <!-- <el-dialog :visible="showDialog" @close="handleClose"> -->
    <!-- 内部封装 el-dialog 的时候，肯定会有一行代码，this.$emit('update:visible', false) -->
    <el-dialog title="图片预览" :visible.sync="showDialog">
      <!-- src 是动态的，点某一个张图片的时候，只需要把当前点击的这一张图片的地址给 imgUrl -->
      <img :src="imgUrl" width="100%">
    </el-dialog>
  </div>
</template>
<script>
import COS from 'cos-js-sdk-v5'
// 官方教程：https://cloud.tencent.com/document/product/436/11459#.E9.85.8D.E7.BD.AE.E9.A1.B9
// 通过下面这个链接可以拿到 SecretId 和 SecretKey
// https://console.cloud.tencent.com/cam/capi
// 创建 cos 实例
const cos = new COS({
  SecretId: 'AKIDQmu0HrSQcZeU3cqA4iCcmgYidIhrQrjy',
  SecretKey: 'jDRPmTx8rrdBTWXINPltwjKvJRmqfEYl'
})
export default {
  name: 'ImageUpload',
  data() {
    return {
      fileList: [],
      // 控制弹框的显示隐藏
      showDialog: false,
      // 控制图片地址的
      imgUrl: ''
    }
  },
  // 计算属性：根据 this.fileList 的长度和 limit 的关系，控制计算出来的变量的值
  // 如果 this.fileList.length === limit，结果就是 true，我就隐藏加号按钮
  computed: {
    isShowAdd() {
      return this.fileList.length === 1
    },
    // !#2 表示是否所有的图片都上传完毕
    isAllImgSuccess() {
      return this.fileList.every(item => item.status === 'success')
    }
  },

  methods: {
    handdlePriview(file) {
      this.imgUrl = file.url
      this.showDialog = true
    },
    handleClose() {
      this.showDialog = false
    },
    handleRemove(file, fileList) {
      // file => 当前删除的文件对象
      // fileList => 删完之后的结果
      // console.log(file)
      // console.log(fileList)
      // 不建议直接赋值，因为对象的赋值，其实赋值的是引用地址，修改的时候会相互影响，这往往不是我们期望的
      // this.fileList = fileList
      // !其实即便下面写法，改 this.fileList 内部的对象的话也会相互影响（除非深拷贝），但是改数组本身不会相互影响
      // this.fileList = [...fileList]
      this.fileList = this.fileList.filter(item => item.uid !== file.uid)
    },
    handleUpload(params) {
      // params.file 表示当前选择的文件对象，我们还希望把选择到的文件信息放到 this.fileList 中一份，目的是为了视图和数据保持同步
      // 但是由于 params.file 没有 url，所以不能直接放到 this.fileList 中
      // console.log(params.file)
      // 自己的上传逻辑
      // params.file 里面包含了当前实实在在选中的文件信息，也有 elementui 自动加进去的一些内容，例如 uid
      // 从 this.fileList 中找到当前的这一个文件对象，这个文件对象说的是 this.fileList 中的某一项
      const currentFile = this.fileList.find(item => item.uid === params.file.uid)
      // 把【当前文件对象】的 status 改为 uploading，表示正在上传
      currentFile.status = 'uploading'
      cos.uploadFile({
        Bucket: 'ifer-1253924894', /* 桶的名字 */
        Region: 'ap-nanjing', /* 存储桶所在地域，必须字段 */
        Key: params.file.name, /* 一般用文件名字 */
        Body: params.file, // 上传文件对象
        onProgress: function(progressData) {
          // 加上进度，给当前文件对象的 percentage 赋值，进度信息在 progressData
          // Math.ceil
          currentFile.percentage = parseInt(progressData.percent * 100)
        }
      }, function(err, data) {
        if (err) {
          console.log('上传失败', err)
        } else {
          console.log(data)
          // 记得一定要把腾讯云返回的真实文件地址给当前文件的 url
          currentFile.url = 'https://' + data.Location
          // 上传成功后把【当前文件对象】的status改为 success
          setTimeout(() => {
            currentFile.status = 'success'
          }, 2000)
        }
      })
    },
    changeFile(file, fileList) {
      // fileList => 变化完毕之后的文件列表
      this.fileList = [...fileList]
    },
    beforeUpload(file) {
      // 校验文件类型
      const types = ['image/jpeg', 'image/gif', 'image/bmp', 'image/png']
      if (!types.includes(file.type)) {
        this.$message.error('文件类型不符合')
        return false
      }
      // 校验文件大小
      const isMore5M = file.size / 1024 / 1024 > 5
      if (isMore5M) {
        this.$message.error('上传的文件不能超过5兆')
        return false
      }
      return true
    }
  }
}
</script>
<style scoped lang="scss">
/* .isShowAdd .el-upload--picture-card {display: none;} */

/* 如果外部加了 scoped 要使用深度作用选择器 */
.isShowAdd{
  ::v-deep {
    .el-upload--picture-card {display: none;}
  }
}
</style>
